﻿/************************************************************************
 * AIDE/Tools - Automata Identification Engine
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     
 * Description  :     
 * Change log   :     	-Date:  Change
 ************************************************************************/
using System;
using System.Collections.Generic;
using MBT.TestStateLevel;
using MBT.Modeling;
using MBT;

namespace TestingApp
{
	public class Program
	{
		class Options
		{
			public Options ()
			{

			}

			public string ModelName;
			public List<string> libs;
			public string dotPath;
			public bool help;
		}

		private static Options ParseParams (string[] args)
		{
			Options opt = new Options ();
			for (int i=0; i<args.Length; i++) {
				switch (args [i]) {
				case "-help":
					opt.help = true;	
					break;

				case "-l":
					if (i >= args.Length)
						throw new Exception ("Exception: After -l parameter, the list of library is expected");
					i++;
					opt.libs = new List<string> ();
					for (; i<args.Length; i++) {						
						if (args [i].StartsWith ("-")) {
							i--;	
							break;
						}
						opt.libs.Add (args [i]);
					}
					break;
				case "-d":
					if (i >= args.Length)
						throw new Exception ("Exception: After -d parameter, path of dot file is expected");
					i++;
					opt.dotPath = (args [i]);
					break;
				case "-m":
					if (i >= args.Length)
						throw new Exception ("Exception: After -m parameter, name of model is expected");
					i++;
					opt.ModelName = (args [i]);
					break;							
				}				
			}
			return opt;
		}
		/*		
		static string exPath = "myChatSystem.dot";
		static void RunChatTestExample (int n)
		{
			TestAutomaton ss;
			//Read From DLL Directly
			ModelCreator mc = new ModelCreator ();
			mc.AddLibrary (System.IO.Directory.GetCurrentDirectory () + "/TestingApp.exe");
            
			Console.WriteLine ("Reading the model and generate an executable file...");
			ChatModel.NUMBER = n;
			TestModel mm = mc.CreateComposed (TFTP_Model.Construct ());
			//TestModel mm = mc.CreateComposed(ChatModel.Construct());

			
			Console.WriteLine ("\nDone!\nNow, analyse the model and generate state space...");
			TA_Generator generator = new TA_Generator (mm);

			
			ss = generator.GenerateStateSpace ();

			Console.WriteLine ("State Space Size = " + ss.Size);
			Console.WriteLine ("Done, Save the model into DOT format...");
			//Save as DOT

			DotHelper_TA.WriteToDot (exPath, ss);

			Console.WriteLine ("Model generation Done, Press any key to show graphical representation...");
			Console.ReadKey ();

			//Visualization.SSViewer<TestState, TestState.Transition> viewer = new Visualization.SSViewer<TestState, TestState.Transition>(ss);
			//viewer.ShowDialog();
			//Console.ReadKey();
		}
		*/
		static void GenerateModel (List<string> libs, string name, string dotPath)
		{
			TestAutomaton ss;
			//Read From DLL Directly
			ModelCreator mc = new ModelCreator ();
			for (int y=0; y<libs.Count; y++)
				mc.AddLibrary (libs [0]);
			            
			Console.WriteLine ("Reading the model and generate an executable file...");
			
			
			LoadTestModel loader = new LoadTestModel (libs [0]);
			
			TestModel mm = mc.CreateComposed (loader.Load (name));
			//TestModel mm = mc.CreateComposed(ChatModel.Construct());

			
			Console.WriteLine ("\nDone!\nNow, analyse the model and generate state space...");
			TA_Generator generator = new TA_Generator (mm);
			
			ss = generator.GenerateStateSpace ();

			Console.WriteLine ("State Space Size = " + ss.Size);
			Console.WriteLine ("Done, Save the model into DOT format into " + dotPath);
			
			//* Save as DOT
			DotHelper_TA.WriteToDot (dotPath, ss);

			Console.WriteLine ("Model generation Done!");
			//Console.ReadKey ();
		}

		public static void Main (string[] args)
		{
			//RunChatTestExample (1);
			Options opt = ParseParams (args);
			//Console.WriteLine("Model:"+opt.ModelName);
			//Console.WriteLine("Dot output:"+opt.dotPath);
			/*
			opt.libs.Add (
				System.IO.Path.GetDirectoryName (System.Reflection.Assembly.GetExecutingAssembly ().Location) 
				+ "SMLib1.dll");
				*/
			/*
			opt.libs=new List<string>();
			opt.libs.Add("counter.dll");
			opt.ModelName="Examples.Counter";
			opt.dotPath="counter.dot";
			*/

			if (opt.dotPath == null) {
				Console.WriteLine ("The dot path cannot be null!");
				return;
			}

			GenerateModel (opt.libs, opt.ModelName, opt.dotPath);
			
		}
	}
}
